package com.itheima.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.dao.MenuDao;
import com.itheima.dao.PermissionDao;
import com.itheima.dao.RoleDao;
import com.itheima.dao.UserDao;
import com.itheima.entity.PageResult;
import com.itheima.entity.QueryPageBean;
import com.itheima.pojo.Permission;
import com.itheima.pojo.Role;
import com.itheima.pojo.User;
import com.itheima.service.UserService;
import com.itheima.utils.DateUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 用户接口实现类
 */
@Service
@Transactional
public class UserServiceImpl implements UserService {
    
    //注入UserDao对象
    @Autowired
    private UserDao userDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private PermissionDao permissionDao;
    @Autowired
    private MenuDao menuDao;

    //根据用户名查询数据库,获取用户信息和关联的角色信息,同时需要查询角色关联的权限信息
    @Override
    public User findByUsername(String username) {
        User user = userDao.findByUsername(username);   //查询用户基本信息,不包含用户的角色
        if (user == null) {
            return null;
        }
        Integer userId = user.getId();
        //根据用户ID查询对应的角色
        Set<Role> roles = roleDao.findByUserId(userId);
        for (Role role : roles) {
            Integer roleId = role.getId();
            //根据角色查询对应的权限
            Set<Permission> permissions = permissionDao.findByRoleId(roleId);
            role.setPermissions(permissions);   //让角色关联权限
        }
        user.setRoles(roles);   //让用户关联角色
        return user;
    }

    //新增
    public void add(User user, Integer[] roleIds) {
        userDao.add(user);
        Integer userId = user.getId();
        setUserAndRole(roleIds, userId);
    }

    private void setUserAndRole(Integer[] roleIds, Integer userId) {
        if (roleIds != null && roleIds.length > 0) {
            for (Integer roleId : roleIds) {
                Map<String, Integer> map = new HashMap<String, Integer>();
                map.put("userId", userId);
                map.put("roleId", roleId);
                userDao.setUserAndRole(map);
            }
        }
    }

    public PageResult pageQuery(QueryPageBean queryPageBean) {
        Integer pageSize = queryPageBean.getPageSize();
        Integer currentPage = queryPageBean.getCurrentPage();
        String queryString = queryPageBean.getQueryString();
        PageHelper.startPage(currentPage, pageSize);
        Page<User> page = userDao.findByCondition(queryString);
        List<User> rows = page.getResult();
        long total = page.getTotal();
        return new PageResult(total, rows);
    }

    //编辑
    public void edit(User user, Integer[] roleIds) {
        //修改checkGroup数据
        userDao.edit(user);
        //根据id删除原有的数据关联
        userDao.deleteAssocication(user.getId());
        //插入新的数据关联
        setUserAndRole(roleIds, user.getId());
    }

    @Override
    public User findById(Integer id) {
        return userDao.findById(id);
    }

    @Override
    public List<Integer> findRoleIdsByUserId(Integer id) {
        return userDao.findRoleIdsByUserId(id);
    }

    //删除
    public void delete(Integer id) {
        userDao.deleteAssocication(id);
        userDao.delete(id);
    }

    @Override
    public Set<Map<String, Object>> findMenu(String userName) {
        //调用userDao，根据用户名称查询用户所有角色
        List<Role> rolelist=userDao.findRoleByuserName(userName);
        //创建Set集合
        Set<Integer> menuset = new HashSet<>();
        //遍历角色
        for (Role role : rolelist) {
            //调用roleDao，根据角色Id查询所对应菜单的所有ID
            List<Integer> menuIds = roleDao.findmenuByroleId(role.getId());
            //遍历，将角色的所有菜单ID存入Set集合（去重菜单ID）
            for (Integer menuId : menuIds) {
                menuset.add(menuId);
            }
        }
        //创建list集合
        List<Map<String,Object>> menulist = new ArrayList<>();
        //创建Set集合
        HashSet<Map<String,Object>> menuset1 = new HashSet<>();
        //遍历菜单ID
        for (Integer menuId : menuset) {
            //调用menuDao，根据菜单ID查询菜单
            Map<String,Object> menuMap=menuDao.findmapById(menuId);
            //获取返回菜单的parentMenuId
            Integer parentMenuId = (Integer) menuMap.get("parentMenuId");
            //判断，当parentMenuId不为null时，说明菜单为二级菜单
            if (parentMenuId!=null){
                //调用menuDao，根据菜单parentMenuId查询父菜单
                Map<String,Object> menuMap1=menuDao.findparentMenuIdBymenu(parentMenuId);
                //将父菜单存入Set（menuset1）集合（可能和已有的一级菜单重复，去重）
                menuset1.add(menuMap1);
                //将二级菜单存入list（menulist）集合
                menulist.add(menuMap);
            }else {
                //为null时，说明是一级菜单，存入Set（menuset1）集合
                menuset1.add(menuMap);
            }
        }
        //遍历set集合
        for (Map<String, Object> map : menuset1) {
            //获取到一级菜单中的path，并转换为int格式
            String path = (String) map.get("path");
            int path1 = Integer.parseInt(path);
            //创建list集合（用于存储此菜单下的所有子菜单）
            ArrayList<Map<String, Object>> list = new ArrayList<>();
            //遍历menulist集合
            for (Map<String, Object> parentMap : menulist) {
                //获取子菜单的parentMenuId
                Integer parentMenuId = (Integer) parentMap.get("parentMenuId");
                //判断，当path1==parentMenuId时，说明此菜单是一级菜单下的子菜单
                if (path1==parentMenuId){
                    //将子菜单存入list（list）集合
                    list.add(parentMap);
                }
            }
            //将list集合添加到map
            map.put("children",list);
        }
        //返回set集合
        return menuset1;
    }
}
